In the latter half of the twentieth century, there began a phenomenon known as the information revolution. While the information revolution is a historical development broader in scope than any one event or machine, no single device has come to represent the information revolution more than the digital electronic computer. The development of computer systems has surely been a revolution. Each year, computer systems grow faster, store more data, and provide more applications to their users.
A modern computer system typically comprises one or more central processing units (CPU) and supporting hardware necessary to store, retrieve and transfer information, such as communication buses and memory. It also includes hardware necessary to communicate with the outside world, such as input/output controllers or storage controllers, and devices attached thereto such as keyboards, monitors, tape drives, disk drives, communication lines coupled to a network, etc. The CPU or CPUs are the heart of the system. They execute the instructions which comprise a computer program and direct the operation of the other system components.
From the standpoint of the computer's hardware, most systems operate in fundamentally the same manner. Processors are capable of performing a limited set of very simple operations, such as arithmetic, logical comparisons, and movement of data from one location to another. But each operation is performed very quickly. Sophisticated software at multiple levels directs a computer to perform massive numbers of these simple operations, enabling the computer to perform complex tasks. What is perceived by the user as a new or improved capability of a computer system is made possible by performing essentially the same set of very simple operations, but using software having enhanced function, along with faster hardware.
In the very early history of the digital computer, computer programs which instructed the computer to perform some task were written in a form directly executable by the computer's processor. Such programs were very difficult for a human to write, understand and maintain, even when performing relatively simple tasks. As the number and complexity of such programs grew, this method became clearly unworkable. As a result, alternate forms of creating and executing computer software were developed.
Among the techniques introduced for creating software have been the use of high-level languages, the combining of multiple program modules, including libraries of programming code, and the use of integrated development environments. High-level languages vary in their characteristics, but all such languages are intended to make it easier for a human to write a program to perform some task. Typically, high-level languages represent instructions, fixed values, variables, and other constructs in a manner readily understandable to the human programmer rather than the computer. Such programs are not directly executable by the computer's processor. In order to run on the computer, the programs must first be transformed into a form that the processor can execute.
Transforming a high-level language program into executable form requires that the human-readable program form (source code) be converted to a processor-executable form (object code) in a compilation process. For very simple programs, the entire program is potentially compilable as a single unit. However, as programs have grown in complexity, and frequently call or invoke functions and procedures which are parts of other programs, it is often impractical to compile the program as a single unit. In a typical case, individual modules or parts of a program are separately compiled, and a further process, sometimes referred to herein as a build process, gathers the different parts and places references in each part to other parts as required, so that the parts may execute together as a single program.
As programs have grown in sophistication, it is known to employ program libraries of commonly used procedures. A program library is not intended to function as a stand-alone program, but is instead a collection of executable procedures or functions which may be used by other programs. Often, a program library has some common theme to the procedures contained therein for supporting applications of a certain family, such as an accounting library, a database library, a graphics library, and so forth. It is usually intended that such libraries be incorporated into many different applications by linking or binding to the application program, although it is not necessarily true that each application program will use all of the procedures in the library. The program library may contain many separately compiled individual modules.
Large software applications are usually developed using sophisticated integrated development environments, which include the capabilities to edit source code, manage program libraries, compile individual modules, build applications from collections of modules, debug executable code, and/or other capabilities. These various functions of an integrated development environment are often embodied as a suite of applications intended to work together, although such an environment may be assembled from separate programs, or might even be a single combined application program having different invokable functions.
Despite the great progress that has been made in the field of software development tools and support, these development systems can barely keep up with the growing complexity of the software being created. Software development remains a very expensive and time consuming process. As the demand for more sophisticated software grows, the costs of software development will only increase. Viewed in the context of the already enormous resources devoted to software development, even minor or marginal improvements to software developers' productivity can have significant aggregate cost benefits. There is, therefore, a continuing need, now and in the future, for improved software development techniques and tools, which will counter the inevitable rising costs of software development.
In many cases, the starting point for an improvement is a realization, not always generally recognized by those of skill in the art, that some commonly performed technique is itself less than optimal, and might be improved. In the case of software development, one such common technique is the copying of a section of code into multiple different locations. Conventional source editors make it relatively simple to copy a code fragment into different locations in a source module, or into different source modules. Such copying is often performed before the code fragment has gone through certain verification processes, such as those inherent in compilation. If a code module or modules are verified after making multiple copies of the same fragment, and an error is found during verification, it is generally necessary to manually edit each individual fragment copy. This editing is repetitive, since the same mistake is generally propagated to all the copies. In addition to the time required for correcting the same information multiple times, this introduces the possibility that the software developer (referred to herein for simplicity as the programmer) will make a further mistake on one or more of the copies, requiring further correction after a second compilation.